package com.fucheng.transport;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * Netty 服务端基础框架
 */
public class NettyRpcServer {

    private final int port;

    public NettyRpcServer(int port) {
        this.port = port;
    }

    public void start() {
        // boss处理连接事件，worker处理读写事件
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try{
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class) // 使用 NIO 通道(异步)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline p = socketChannel.pipeline();

                            // TODO: 添加编解码器
                            p.addLast(new RpcEncoder()); // ByteBuf -> RpcRequest
                            // TODO: 添加请求处理器
                            p.addLast(new RpcDecoder()); // RpcResponse -> ByteBuf

                            p.addLast(new SimpleServerHandler()); // 暂时用占位处理器

                        }
                    });

            ChannelFuture f = bootstrap.bind(port).sync();
            System.out.println("[Netty] 服务端启动完成，监听端口：" + port);
            f.channel().closeFuture().sync(); // 阻塞直到服务器关闭

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
